package com.dsunsoft.rtu.netty;

import com.dsunsoft.rtu.common.util.CommonUtils;
import com.dsunsoft.rtu.common.util.ConvertUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

/**
 * netty 客户端
 */
@Slf4j
public class NettyClient {
    /**
     * 服务器地址
     */
    private final String host;
    /**
     * 服务器端口
     */
    private final int port;
    /**
     * group
     */
    private EventLoopGroup group;
    /**
     * channel
     */
    private Channel channel;

    NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    /**
     * connect
     */
    public void connect() throws InterruptedException {
        this.group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                // 使用NioServerSocketChannel 作为服务器的通道实现
                .channel(NioSocketChannel.class)
                // handler
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast("decoder", new ByteArrayDecoder());
                        p.addLast("encoder", new ByteArrayEncoder());
                        p.addLast(new NettyClientHandler());
                    }
                });

        ChannelFuture future = bootstrap.connect(this.host, this.port).sync();
        if (future.isSuccess()) {
            log.info("连接服务器成功!");
            this.channel = future.channel();
        }
    }

    /**
     * disConnect
     */
    public void disConnect() throws InterruptedException {
        if (this.channel != null) {
            this.channel.disconnect();
            this.channel.close();
            this.channel = null;
        }
        if (this.group != null) {
            this.group.shutdownGracefully().sync();
            this.group = null;
        }
    }

    /**
     * sendMessage
     *
     * @param message
     */
    public void sendMessage(byte[] message) {
        log.info("sendMessage: " + CommonUtils.bytesToHexString(message));
        this.channel.writeAndFlush(message);
    }

    public static void main(String[] args) {
        try {
            // 心跳 970000010009686561727462656174
            // 数据 97960001000B0703080011002500380080
            NettyClient client = new NettyClient("127.0.0.1", 9001);
            client.connect();
            byte[] msg = CommonUtils.hexToBytes("970000010009686561727462656174");
            client.sendMessage(msg);
            client.disConnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
